<script lang="ts" setup>
import {useMsgStore} from "@/store/modules";
import MarkdownCards from "@/components/MarkdownCards.vue";
import {configSetParam} from "@/utils";
import {RoleType} from "@coze/api";

const msgStore = useMsgStore();
const {msg} = storeToRefs(msgStore);
const router = useRouter();
const showPopup = ref(false)
const goBack = () => {
  router.back();
};
const messagesContainer = ref(null);
const isLoading = ref(false);
const messages = ref([]);
const sendMessage = async (info: string) => {
  if (info.trim() === "") return;
  isLoading.value = true;
  messages.value.push({
    role: RoleType.User,
    content: info,
    type: "question",
    isSelf: true,
  });
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    }
  });
  await submitData();
  isLoading.value = false;
};
let mIndex = 0;
const submitData = async () => {
  const data = {
    bot_id: configSetParam.botId,
    user_id: "123",
    additional_messages: messages.value,
    stream: true,
  };
  const response = await fetch("https://api.coze.cn/v3/chat", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${configSetParam.token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(data),
  });
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  messages.value.push({
    role: RoleType.Assistant,
    content: "",
    isSelf: false,
    avatar: "https://placeholder.svg?height=40&width=40&text=Me",
  });
  // 获取响应流的读取器
  const reader = response.body.getReader();
  const decoder = new TextDecoder("utf-8"); // 用于解码二进制数据为文本
  // 逐块读取数据并更新 UI
  while (true) {
    const {done, value} = await reader.read();
    if (done) break;
    // 解码数据
    const chunk = decoder.decode(value, {stream: true});
    // 处理SSE格式的数据
    const lines = chunk.split("event:").filter((line) => line.trim() !== "");
    for (const line of lines) {
      if (line.startsWith("conversation.message.delta")) {
        let data = line.split("\n")[1].substring(5);
        if (data === "[DONE]") continue;
        try {
          const parsed = JSON.parse(data);
          const {role, type, content} = parsed;
          mIndex = messages.value.length - 1;
          updateAiMessage(content);
        } catch (error) {
          console.error("解析响应数据失败:", error);
        }
      }
      // if (line.startsWith('conversation.message.completed')) {
      //   let data = line.split('\n')[1].substring(5)
      //   if (data === '[DONE]') continue;
      //   try {
      //     const parsed = JSON.parse(data);
      //     const { role, type, content } = parsed;
      //     if (role === 'assistant' && type === 'answer') {
      //       updateAiMessage(content);
      //     } else {
      //       // console.log('[%s]:[%s]:%s', role, type, content);
      //     }
      //   } catch (error) {
      //     console.error('解析响应数据失败:', error);
      //   }
      // }
    }
  }
};

let timer = null;
let lastStr = "";
const updateAiMessage = (content) => {
  lastStr += content;
  if (timer) {
    clearTimeout(timer);
  }
  // timer = setTimeout(() => {
    messages.value[mIndex].content += lastStr;
    lastStr = "";
  // }, 300);
  // 自动滚动到底部
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    }
  });
};
onMounted(async () => {
  // 初始滚动到底部
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
  }
  sendMessage(msg.value);
});
</script>
<template>
  <div class="chat">
      <div class="header">
        <van-icon
            class="back"
            size="24"
            color="#29898e"
            name="arrow-left"
            @click="goBack"
        />
       <p class="header-title">橘子洲AI客服</p>
        <div class="avatar" style="margin-left: auto;">
          <img class="service" src="@/assets/images/index/service.svg" alt="" @click="showPopup = true" />
        </div>

      </div>
    <van-popup v-model:show="showPopup" round>
      <div class="qrcode-wrap">
        <img class="qrcode" src="@/assets/images/index/qrcode.svg" alt="">
      </div>
    </van-popup>
    <div class="chatInfo">
      <div class="chat-messages" ref="messagesContainer">
        <div
            v-for="(message, index) in messages"
            :key="index"
            :class="['message-wrapper', message.isSelf ? 'self' : 'other']"
        >
          <div  class="message-content" v-if="message.content && message.isSelf">
            <div  class="message-bubble">
              <p>{{message.content}}</p>
            </div>
          </div>
          <markdown-cards v-else :markdown-text="message.content" />
        </div>
      </div>
      <!-- 加载指示器 -->
      <div class="typing-indicator" v-if="isLoading">
        <span>.</span>
        <span>.</span>
        <span>.</span>
      </div>
    </div>
    <public-input :disabled="isLoading" @send="sendMessage"/>
  </div>
</template>

<style scoped lang="scss">
.service {
  position: absolute;
  top: 50px;
  left: 0px;
  width: 70px;
  height: 70px;
}
.qrcode-wrap{
  padding: 40px;
  border-radius: 16px;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  .qrcode{
    width: 161px;
    height: 159px;
  }
}
.chat {
  width: 100%;
  height: 100%;
  padding: 16px;
  box-sizing: border-box;
  background: linear-gradient(180deg, #faf5ff 0%, #ffffff 100%), rgba(0, 0, 0, 0);
  position: relative;

  .chatInfo {
    width: 100%;
    height: calc(100% - 90px);
    margin-top: 50px;
    // height: calc(100% - 40px);
    overflow: hidden;
  }

  .chat-header {
    padding: 10px 15px;
    // background-color: #f6f6f6;
    border-bottom: 1px solid #e6e6e6;
    text-align: center;

    .chat-title {
      font-size: 16px;
      font-weight: 500;
      color: #000;
    }
  }

  .chat-messages {
    height: calc(100% - 40px);
    overflow-y: auto;

    .message-wrapper {
      display: flex;
      margin-bottom: 15px;

      &.self {
        flex-direction: row-reverse;

        .message-content {
          align-items: flex-end;
        }

        .message-bubble {
          background-color: #29898e; // 微信绿色气泡
          border-radius: 4px 0 4px 4px;
          margin-left: 0;
          color: #fff;
        }

        .message-time {
          text-align: right;
        }
      }

      &.other {
        .message-bubble {
          background-color: #fff;
          border-radius: 0 4px 4px 4px;

          ::v-deep(img) {
            max-width: 150px;
            // height: fit-content;
            height: auto;
            display: block;

            &:focus {
              transform: scale(2.5);
            }
          }
        }
      }
    }

    .avatar {
      width: 40px;
      height: 40px;
      border-radius: 4px;
      overflow: hidden;

      img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }

    .message-content {
      display: flex;
      flex-direction: column;
      max-width: 80%;

      .sender {
        font-size: 12px;
        color: #999;
        margin-bottom: 2px;
        margin-left: 10px;
      }

      .message-bubble {
        padding: 8px 12px;
        word-break: break-word;
        box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);
      }

      .message-time {
        font-size: 11px;
        color: #999;
        margin-top: 2px;
        padding: 0 12px;
      }
    }
  }

  .typing-indicator {
    background-color: transparent;
    padding: 0 16px;
    margin-top: -20px;

    span {
      font-size: 40px;
      margin-right: 3px;
      animation: typing 1s infinite;
      display: inline-block;

      &:nth-child(2) {
        animation-delay: 0.2s;
      }

      &:nth-child(3) {
        animation-delay: 0.4s;
      }
    }
  }

  @keyframes typing {
    0%,
    60%,
    100% {
      transform: translateY(0);
    }
    30% {
      transform: translateY(-10px);
    }
  }
}
</style>
